package nsu.edu.zsq.service.impl.sys;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import lombok.extern.slf4j.Slf4j;
import nsu.edu.zsq.bean.SysLog;
import nsu.edu.zsq.bean.SysLogExample;
import nsu.edu.zsq.common.RequestHolder;
import nsu.edu.zsq.dao.SysLogMapper;
import nsu.edu.zsq.exception.ParamException;
import nsu.edu.zsq.param.PageQuery;
import nsu.edu.zsq.param.SysLogSearch;
import nsu.edu.zsq.service.sys.SysLogService;
import nsu.edu.zsq.util.BeanValidator;
import nsu.edu.zsq.util.JsonMapper;
import nsu.edu.zsq.util.UserType;

/** 
* Description: 系统的操作日志service实现类<br>
*/
@Slf4j
@Service
public class SysLogServiceImpl implements SysLogService {
    
    @Autowired
    private SysLogMapper sysLogMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveSysLogBySysUser(Object before, Object after, String instruction) {
        // 保存日志时出现异常，不能影响其它操作，所以这里应该捕获异常
        try {
            SysLog sysLog = new SysLog();
            sysLog.setType(UserType.TYPE_SYSUSER);
            sysLog.setInstruction(instruction == null ? "" : instruction);
            sysLog.setOldValue(before == null ? "" : JsonMapper.obj2String(before));
            sysLog.setNewValue(after == null ? "" : JsonMapper.obj2String(after));
            sysLog.setOperator(RequestHolder.getCurrentSysUser().getAccount());
            sysLog.setOperatorTime(new Date());
            sysLogMapper.insertSelective(sysLog);
            log.info("添加系统操作日志成功，日志内容：{}",sysLog);
        } catch (Exception e) {
            log.info("添加系统操作日志失败，exception：{}",e);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveSysLogByTeacher(Object before, Object after, String instruction) {
        // 保存日志时出现异常，不能影响其它操作，所以这里应该捕获异常
        try {
            SysLog sysLog = new SysLog();
            sysLog.setType(UserType.TYPE_TEACHER);
            sysLog.setInstruction(instruction == null ? "" : instruction);
            sysLog.setOldValue(before == null ? "" : JsonMapper.obj2String(before));
            sysLog.setNewValue(after == null ? "" : JsonMapper.obj2String(after));
            sysLog.setOperator(RequestHolder.getCurrentTeacher().getTeacherNo());
            sysLog.setOperatorTime(new Date());
            log.info("添加系统操作日志成功，日志内容：{}",sysLog);
            sysLogMapper.insertSelective(sysLog);
        } catch (Exception e) {
            log.info("添加系统操作日志失败，exception：{}",e);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveSysLogByStudent(Object before, Object after, String instruction) {
        // 保存日志时出现异常，不能影响其它操作，所以这里应该捕获异常
        try {
            SysLog sysLog = new SysLog();
            sysLog.setType(UserType.TYPE_STUDENT);
            sysLog.setInstruction(instruction == null ? "" : instruction);
            sysLog.setOldValue(before == null ? "" : JsonMapper.obj2String(before));
            sysLog.setNewValue(after == null ? "" : JsonMapper.obj2String(after));
            sysLog.setOperator(RequestHolder.getCurrentStudent().getStuNo());
            sysLog.setOperatorTime(new Date());
            log.info("添加系统操作日志成功，日志内容：{}",sysLog);
            sysLogMapper.insertSelective(sysLog);
        } catch (Exception e) {
            log.info("添加系统操作日志失败，exception：{}",e);
        }
    }

    @Override
    public PageInfo<SysLog> listSysLogWithPage(PageQuery pageQuery) {
        SysLogExample example = new SysLogExample();
        example.setOrderByClause("operator_time DESC");
        PageHelper.startPage(pageQuery.getPageNum(),pageQuery.getPageSize());
        List<SysLog> listSysLog = sysLogMapper.selectByExample(example);
        PageInfo<SysLog> pageInfo = new PageInfo<SysLog>(listSysLog, pageQuery.getNavigatePages());
        return pageInfo;
    }
    
    @Override
    public PageInfo<SysLog> listSysLogWithPageBySearch(SysLogSearch sysLogSearch, PageQuery pageQuery) {
        BeanValidator.check(sysLogSearch);
        String operator = sysLogSearch.getOperator();
        String oldValue = sysLogSearch.getOldValue();
        String newValue = sysLogSearch.getNewValue();
        if (StringUtils.isNotBlank(operator)) {
            StringBuilder sb = new StringBuilder();
            sb.append("%");
            sb.append(operator);
            sb.append("%");
            sysLogSearch.setOperator(sb.toString());
        }
        if (StringUtils.isNotBlank(oldValue)) {
            StringBuilder sb = new StringBuilder();
            sb.append("%");
            sb.append(oldValue);
            sb.append("%");
            sysLogSearch.setOldValue(sb.toString());
        }
        if (StringUtils.isNotBlank(newValue)) {
            StringBuilder sb = new StringBuilder();
            sb.append("%");
            sb.append(newValue);
            sb.append("%");
            sysLogSearch.setNewValue(sb.toString());
        }
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            if (StringUtils.isNotBlank(sysLogSearch.getFromTime())) {
                dateFormat.parse(sysLogSearch.getFromTime());
            }
            if (StringUtils.isNotBlank(sysLogSearch.getToTime())) {
                dateFormat.parse(sysLogSearch.getToTime());
            }
        } catch (Exception e) {
            throw new ParamException("传入的日期格式有问题，正确格式为：yyyy-MM-dd HH:mm:ss");
        }
        PageHelper.startPage(pageQuery.getPageNum(),pageQuery.getPageSize());
        List<SysLog> listSysLogBySearch = sysLogMapper.listSysLogBySearch(sysLogSearch);
        PageInfo<SysLog> pageInfo = new PageInfo<SysLog>(listSysLogBySearch, pageQuery.getNavigatePages());
        return pageInfo;
    }

}
